Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / tests / backend / test_websocket_scale.py

Displaying Raw • Download


tests/backend/test_websocket_scale.py b1b9846ac58289ad2ac7f6564863fc97dd720128 (b1b9846a) Text, 3.98 KB

T8b949e"""Scale and concurrency tests for websocket broadcast fan-out (core architecture)."""

Tff7b72from T7ee787__future__ Tff7b72import Te6edf3annotations

Tff7b72import T7ee787asyncio
Tff7b72from T7ee787unittestT7ee787.T7ee787mock Tff7b72import Te6edf3AsyncMock

Tff7b72import T7ee787pytest
Tff7b72from T7ee787hypothesis Tff7b72import Te6edf3HealthCheckTb4b4b4, Te6edf3givenTb4b4b4, Te6edf3settings
Tff7b72from T7ee787hypothesis Tff7b72import Te6edf3strategies Tff7b72as Te6edf3st

Tff7b72from T7ee787meshchatxT7ee787.T7ee787meshchat Tff7b72import Te6edf3ReticulumMeshChat


Tff7b72def Td2a8ff_bind_real_websocket_broadcastTb4b4b4(Te6edf3appTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3ReticulumMeshChatTff7b72.Td2a8ffwebsocket_broadcastTff7b72.Td2a8ff__get__Tb4b4b4(Te6edf3appTb4b4b4, Te6edf3ReticulumMeshChatTb4b4b4)


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_websocket_broadcast_fanout_many_clientsTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clientsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Te6edf3n Tff7b72= T79c0ff400
Te6edf3clients Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(Te6edf3nTb4b4b4)Tb4b4b4:
Te6edf3c Tff7b72= Te6edf3MagicWsTb4b4b4(Tb4b4b4)
Te6edf3clientsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3cTb4b4b4)
Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clientsTff7b72.Td2a8ffextendTb4b4b4(Te6edf3clientsTb4b4b4)

Te6edf3real Tff7b72= Te6edf3_bind_real_websocket_broadcastTb4b4b4(Te6edf3mock_appTb4b4b4)
Te6edf3payload Tff7b72= Ta5d6ff'Ta5d6ff{Ta5d6ff"Ta5d6fftypeTa5d6ff"Ta5d6ff:Ta5d6ff"Ta5d6ffconfigTa5d6ff"Ta5d6ff,Ta5d6ff"Ta5d6ffconfigTa5d6ff"Ta5d6ff:Tffd700{}Ta5d6ff}Ta5d6ff'
Tff7b72await Te6edf3realTb4b4b4(Te6edf3payloadTb4b4b4)

Tff7b72for Te6edf3c Tff7b72in Te6edf3clientsTb4b4b4:
Tff7b72assert Te6edf3cTff7b72.Td2a8ffsend_strTff7b72.Td2a8ffawait_count Tff7b72== T79c0ff1
Tff7b72assert Te6edf3cTff7b72.Td2a8ffsend_strTff7b72.Td2a8ffawait_argsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[T79c0ff0Tb4b4b4] Tff7b72== Te6edf3payload


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_websocket_broadcast_concurrent_broadcastsTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clientsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Te6edf3clients Tff7b72= Tb4b4b4[Te6edf3MagicWsTb4b4b4(Tb4b4b4) Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(T79c0ff120Tb4b4b4)Tb4b4b4]
Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clientsTff7b72.Td2a8ffextendTb4b4b4(Te6edf3clientsTb4b4b4)
Te6edf3real Tff7b72= Te6edf3_bind_real_websocket_broadcastTb4b4b4(Te6edf3mock_appTb4b4b4)

Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffgatherTb4b4b4(
Te6edf3realTb4b4b4(Ta5d6ff'Ta5d6ff{Ta5d6ff"Ta5d6fftypeTa5d6ff"Ta5d6ff:Ta5d6ff"Ta5d6ffaTa5d6ff"Ta5d6ff}Ta5d6ff'Tb4b4b4)Tb4b4b4,
Te6edf3realTb4b4b4(Ta5d6ff'Ta5d6ff{Ta5d6ff"Ta5d6fftypeTa5d6ff"Ta5d6ff:Ta5d6ff"Ta5d6ffbTa5d6ff"Ta5d6ff}Ta5d6ff'Tb4b4b4)Tb4b4b4,
Te6edf3realTb4b4b4(Ta5d6ff'Ta5d6ff{Ta5d6ff"Ta5d6fftypeTa5d6ff"Ta5d6ff:Ta5d6ff"Ta5d6ffcTa5d6ff"Ta5d6ff}Ta5d6ff'Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72for Te6edf3c Tff7b72in Te6edf3clientsTb4b4b4:
Tff7b72assert Te6edf3cTff7b72.Td2a8ffsend_strTff7b72.Td2a8ffawait_count Tff7b72== T79c0ff3


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_websocket_broadcast_soak_iterationsTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clientsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Te6edf3clients Tff7b72= Tb4b4b4[Te6edf3MagicWsTb4b4b4(Tb4b4b4) Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(T79c0ff80Tb4b4b4)Tb4b4b4]
Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clientsTff7b72.Td2a8ffextendTb4b4b4(Te6edf3clientsTb4b4b4)
Te6edf3real Tff7b72= Te6edf3_bind_real_websocket_broadcastTb4b4b4(Te6edf3mock_appTb4b4b4)

Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(T79c0ff60Tb4b4b4)Tb4b4b4:
Tff7b72await Te6edf3realTb4b4b4(Ta5d6fffTa5d6ff'Tffea00{{Ta5d6ff"Ta5d6fftypeTa5d6ff"Ta5d6ff:Ta5d6ff"Ta5d6fftickTa5d6ff"Ta5d6ff,Ta5d6ff"Ta5d6ffiTa5d6ff"Ta5d6ff:Tffd700{Te6edf3iTffd700}Tffea00}}Ta5d6ff'Tb4b4b4)

Tff7b72for Te6edf3c Tff7b72in Te6edf3clientsTb4b4b4:
Tff7b72assert Te6edf3cTff7b72.Td2a8ffsend_strTff7b72.Td2a8ffawait_count Tff7b72== T79c0ff60


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_websocket_broadcast_iterates_snapshot_not_live_listTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
T8b949e"""Broadcast must iterate a snapshot of websocket clients, not the live list.

If another coroutine mutates ``websocket_clients`` during iteration, using
``list(...)`` avoids skipping entries (classic mutating-list pitfall).
"""
Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clientsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Te6edf3clients Tff7b72= Tb4b4b4[Te6edf3MagicWsTb4b4b4(Tb4b4b4) Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(T79c0ff5Tb4b4b4)Tb4b4b4]
Te6edf3lst Tff7b72= Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clients
Te6edf3lstTff7b72.Td2a8ffextendTb4b4b4(Te6edf3clientsTb4b4b4)

Tff7b72async Tff7b72def Td2a8ffremove_last_clientTb4b4b4(Te6edf3_dataTb4b4b4)Tb4b4b4:
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0Tb4b4b4)
Tff7b72if Te6edf3clientsTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72in Te6edf3lstTb4b4b4:
Te6edf3lstTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3clientsTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4)

Te6edf3clientsTb4b4b4[T79c0ff1Tb4b4b4]Tff7b72.Td2a8ffsend_str Tff7b72= Te6edf3AsyncMockTb4b4b4(Te6edf3side_effectTff7b72=Te6edf3remove_last_clientTb4b4b4)
Te6edf3real Tff7b72= Te6edf3_bind_real_websocket_broadcastTb4b4b4(Te6edf3mock_appTb4b4b4)
Tff7b72await Te6edf3realTb4b4b4(Ta5d6ff"Ta5d6ffxTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3clientsTb4b4b4[T79c0ff4Tb4b4b4]Tff7b72.Td2a8ffsend_strTff7b72.Td2a8ffawait_count Tff7b72== T79c0ff1
Tff7b72for Te6edf3c Tff7b72in Te6edf3clientsTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4]Tb4b4b4:
Tff7b72assert Te6edf3cTff7b72.Td2a8ffsend_strTff7b72.Td2a8ffawait_count Tff7b72== T79c0ff1


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_websocket_broadcast_drops_dead_clientsTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clientsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Te6edf3bad Tff7b72= Te6edf3MagicWsTb4b4b4(Tb4b4b4)
Te6edf3badTff7b72.Td2a8ffsend_str Tff7b72= Te6edf3AsyncMockTb4b4b4(Te6edf3side_effectTff7b72=Tf85149RuntimeErrorTb4b4b4(Ta5d6ff"Ta5d6ffclosedTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3good Tff7b72= Te6edf3MagicWsTb4b4b4(Tb4b4b4)
Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clientsTff7b72.Td2a8ffextendTb4b4b4(Tb4b4b4[Te6edf3badTb4b4b4, Te6edf3goodTb4b4b4]Tb4b4b4)

Te6edf3real Tff7b72= Te6edf3_bind_real_websocket_broadcastTb4b4b4(Te6edf3mock_appTb4b4b4)
Tff7b72await Te6edf3realTb4b4b4(Ta5d6ff'Ta5d6ff{Ta5d6ff"Ta5d6fftypeTa5d6ff"Ta5d6ff:Ta5d6ff"Ta5d6ffpingTa5d6ff"Ta5d6ff}Ta5d6ff'Tb4b4b4)

Tff7b72assert Te6edf3bad Tff7b72not Tff7b72in Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clients
Tff7b72assert Te6edf3good Tff7b72in Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clients
Tff7b72assert Te6edf3goodTff7b72.Td2a8ffsend_strTff7b72.Td2a8ffawait_count Tff7b72== T79c0ff1


Tff7b72class T56d364MagicWsTb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsend_str Tff7b72= Te6edf3AsyncMockTb4b4b4(Te6edf3return_valueTff7b72=Tff7b72NoneTb4b4b4)


Tf0883e@settingsTb4b4b4(
Te6edf3suppress_health_checkTff7b72=Tb4b4b4[Te6edf3HealthCheckTff7b72.Td2a8fffunction_scoped_fixtureTb4b4b4]Tb4b4b4,
Te6edf3max_examplesTff7b72=T79c0ff20Tb4b4b4,
Te6edf3deadlineTff7b72=Tff7b72NoneTb4b4b4,
Tb4b4b4)
Tf0883e@givenTb4b4b4(
Te6edf3nTff7b72=Te6edf3stTff7b72.Td2a8ffintegersTb4b4b4(Te6edf3min_valueTff7b72=T79c0ff1Tb4b4b4, Te6edf3max_valueTff7b72=T79c0ff128Tb4b4b4)Tb4b4b4,
Te6edf3payloadTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Te6edf3min_sizeTff7b72=T79c0ff0Tb4b4b4, Te6edf3max_sizeTff7b72=T79c0ff512Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_websocket_broadcast_fanout_propertyTb4b4b4(Te6edf3mock_appTb4b4b4, Te6edf3nTb4b4b4, Te6edf3payloadTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clientsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Te6edf3clients Tff7b72= Tb4b4b4[Te6edf3MagicWsTb4b4b4(Tb4b4b4) Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(Te6edf3nTb4b4b4)Tb4b4b4]
Te6edf3mock_appTff7b72.Td2a8ffwebsocket_clientsTff7b72.Td2a8ffextendTb4b4b4(Te6edf3clientsTb4b4b4)
Te6edf3real Tff7b72= Te6edf3_bind_real_websocket_broadcastTb4b4b4(Te6edf3mock_appTb4b4b4)
Tff7b72await Te6edf3realTb4b4b4(Te6edf3payloadTb4b4b4)
Tff7b72for Te6edf3c Tff7b72in Te6edf3clientsTb4b4b4:
Tff7b72assert Te6edf3cTff7b72.Td2a8ffsend_strTff7b72.Td2a8ffawait_count Tff7b72== T79c0ff1
Tff7b72assert Te6edf3cTff7b72.Td2a8ffsend_strTff7b72.Td2a8ffawait_argsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[T79c0ff0Tb4b4b4] Tff7b72== Te6edf3payload


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────